package com.bluegalaxy.nhb.snapi.controller.api.ck;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bluegalaxy.nhb.service.AnalyseSqlService;
import com.bluegalaxy.nhb.snservice.common.utils.DateUtil;
import com.bluegalaxy.nhb.snservice.core.util.FastJsonUtils;
import com.bluegalaxy.nhb.snservice.domain.constant.AppConstant;
import com.bluegalaxy.nhb.snservice.domain.constant.CkConstant;
import com.bluegalaxy.nhb.snservice.domain.vo.api.R;
import com.bluegalaxy.nhb.snservice.domain.vo.api.ck.KeepParamVO;
import com.bluegalaxy.nhb.snservice.service.ck.KeepService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.bluegalaxy.nhb.snservice.domain.constant.CkConstant.*;

/**
 * 留存分析
 */
@RestController
@RequestMapping(AppConstant.APPLICATION_NAME+"/keep")
@Api(value = "留存分析", tags = "留存分析API")
public class KeepController {
    private static Log log = LogFactory.getLog(KeepController.class);


    @Autowired
    private KeepService keepService;

    @Resource
    private AnalyseSqlService sqlService;



    @ResponseBody
    @PostMapping("/findKeep")
    @ApiOperation(value = "查询留存分析", notes = "查询留存分析列表")
    public R findKeep(@RequestBody KeepParamVO  paramVO) {
        log.info("findKeep:"+ FastJsonUtils.toJSONString(paramVO));
        //String转json
//        JSONObject obj=JSONObject.parseObject(jsonString);

//        KeepParamVO paramVO = new KeepParamVO();
//        paramVO.setStartDate("2021-05-12");
//        paramVO.setEndDate("2021-05-13");
//        paramVO.setInitEvent("MPViewScreen");
//        paramVO.setFollowUpEvent("MPViewScreen");
//        paramVO.setKeepDay(7);
        List<Integer> dayList = Stream.iterate(1,n -> n+1).limit(paramVO.getKeepDay()).collect(Collectors.toList());
        log.info("dayList:::"+dayList);
        paramVO.setDayList(dayList);
        List<Integer> sumDayList = Stream.iterate(1,n -> n+1).limit(paramVO.getKeepDay()+1).collect(Collectors.toList()); ;
        log.info("sumDayList:::"+sumDayList);
        paramVO.setSumDayList(sumDayList);
        if (CkConstant.ct_virtual.equals(paramVO.getInitEventCategory())){
            paramVO.setInitEventValue(getVirtualEventValue(paramVO.getJsonParam(),"initEventJson"));
            paramVO.setInitSql(getVirtualSql(paramVO.getJsonParam(),"initEventJson",initRuleTypes));
        }else{
            paramVO.setInitEventValue("'"+paramVO.getInitEvent()+"'");
            paramVO.setInitSql(sqlService.analyseSql(paramVO.getJsonParam(), m_keep, initRuleTypes));
        }
        if (CkConstant.ct_virtual.equals(paramVO.getFollowUpEventCategory())){
            paramVO.setFollowUpEventValue(getVirtualEventValue(paramVO.getJsonParam(),"nextEventJson"));
            paramVO.setFollowUpSql(getVirtualSql(paramVO.getJsonParam(),"nextEventJson",nextRuleTypes));
        }else{
            paramVO.setFollowUpEventValue("'"+paramVO.getFollowUpEvent()+"'");
            paramVO.setFollowUpSql(sqlService.analyseSql(paramVO.getJsonParam(), m_keep,nextRuleTypes));
        }


        paramVO.setConditionSql(sqlService.analyseSql(paramVO.getJsonParam(), m_keep,userAttributes));

        List<String> dateLists = DateUtil.getBetweenStrDates(paramVO.getStartDate(),paramVO.getEndDate());

//        paramVO.set
//        (7) -> IntStream.
        //
        paramVO.setDateList(dateLists);
        long start = System.currentTimeMillis();
        List<Map<String,Object>> mapList = new ArrayList<>();
        int size = dateLists.size();
        int length = 10;
        if (dateLists.size() > length){
            int count = size % length != 0 ? size / length + 1 : size / length;
            for (int i = 0; i < count; i++) {
                List<String> subList = dateLists.subList(i * length, ((length + i * length) < size ? (length + i * length) : size));
                paramVO.setDateList(subList);
                List<Map<String,Object>> resList = keepService.selectKeepList(paramVO);
                mapList.addAll(resList);
            }
        }else{
            mapList=keepService.selectKeepList(paramVO);
        }

        long end = System.currentTimeMillis();
        log.info("查询时长："+(end - start));
//        log.info("mapList:"+mapList);
//        List<KeepResVO> resList = new ArrayList<>();
//        mapList.forEach(map -> {
//            KeepResVO vo = new KeepResVO();
//            vo.setResDate(map.getOrDefault("resDate","").toString());
////            vo.setDaysCount((BigInteger)map.get("daysCount"));
//        });
        log.info("keepRes:"+FastJsonUtils.toJSONString(mapList));
        return R.data(mapList);
    }

    @ResponseBody
    @PostMapping("/findUser")
    @ApiOperation(value = "查询留存分析", notes = "查询留存分析列表")
    public R findUser(@RequestBody KeepParamVO  paramVO) {
        log.info("findUser:"+ FastJsonUtils.toJSONString(paramVO));
        List<Integer> dayList = Stream.iterate(1,n -> n+1).limit(paramVO.getKeepDay()).collect(Collectors.toList());
        log.info("findUser dayList:::"+dayList);
        paramVO.setDayList(dayList);
        List<Integer> sumDayList = Stream.iterate(1,n -> n+1).limit(paramVO.getKeepDay()+1).collect(Collectors.toList()); ;
        log.info("findUser sumDayList:::"+sumDayList);
        paramVO.setSumDayList(sumDayList);
        paramVO.setDateList(DateUtil.getBetweenStrDates(paramVO.getStartDate(),paramVO.getEndDate()));

        paramVO.setInitSql(sqlService.analyseSql(paramVO.getJsonParam(),m_keep,initRuleTypes));
        paramVO.setFollowUpSql(sqlService.analyseSql(paramVO.getJsonParam(),m_keep,nextRuleTypes));
        paramVO.setConditionSql(sqlService.analyseSql(paramVO.getJsonParam(),m_keep,userAttributes));
        long start = System.currentTimeMillis();
        List<Map<String,Object>> mapList=keepService.selectKeepUserList(paramVO);
        long end = System.currentTimeMillis();
        log.info("查询时长："+(end - start));
        log.info("mapList:"+mapList);

        return R.data(mapList);
    }

    @ResponseBody
    @GetMapping("/findKeepGet")
    @ApiOperation(value = "查询留存分析", notes = "查询留存分析列表")
    public R findEventGet(@RequestBody String  jsonString) {
        //String转json
        JSONObject obj=JSONObject.parseObject(jsonString);
//        String startDate=obj.getString("startDate");
//        String endDate=obj.getString("endDate");
//        String combine=obj.getString("combine");
//        String eventName=obj.getString("eventName");
//        String methodName=obj.getString("methodName");
        KeepParamVO paramVO = new KeepParamVO();
        paramVO.setStartDate("2021-05-12");
        paramVO.setEndDate("2021-05-13");
        paramVO.setInitEvent("MPViewScreen");
        paramVO.setFollowUpEvent("MPViewScreen");
//        paramVO.set
//        (7) -> IntStream.
        //
//        Map<String, Object> paramMap =new HashMap<>();
        List<Map<String,Object>> mapList=null;//keepService.selectKeepList(paramVO);
        log.info("mapList:"+mapList);

        return R.data(mapList);
    }


    private String getVirtualSql(JSONObject virtualParam,String jsonKey,String funcType){
        StringBuffer virtualSqls = new StringBuffer();
        if (virtualParam.containsKey(jsonKey)){
            JSONArray jsonArray = virtualParam.getJSONArray(jsonKey);
            for(int i=0;i<jsonArray.size();i++){
                JSONObject jsonParam = jsonArray.getJSONObject(i);
                virtualSqls.append(sqlService.analyseSql(jsonParam, CkConstant.m_event,funcType));
            }

        }

        return virtualSqls.toString();
    }

    private String getVirtualEventValue(JSONObject virtualParam,String jsonKey){
        StringBuffer values = new StringBuffer();
        if (virtualParam.containsKey(jsonKey)){
            JSONArray jsonArray = virtualParam.getJSONArray(jsonKey);
            for(int i=0;i<jsonArray.size();i++){
                JSONObject jsonParam = jsonArray.getJSONObject(i);
                if (i != 0){
                    values.append(",");
                }
                values.append("'");
                values.append(jsonParam.getString("eventType"));
                values.append("'");
            }

        }

        return values.toString();
    }

}
